package com.xiaoshuidi.cloud.framework.pay.core.client;


import com.xiaoshuidi.cloud.framework.pay.core.client.dto.*;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.EnterpriseAccountEstablishReqDTO;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.EnterpriseAccountEstablishRespDTO;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.MemberBindReqDTO;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.MemberBindRespDTO;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.MemberCreateReqDTO;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.MemberCreateRespDTO;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.QueryBalanceReqDTO;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.QueryBalanceRespDTO;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.WithdrawApplyReqDTO;
import com.xiaoshuidi.cloud.framework.pay.core.client.impl.tongshangyun.dto.WithdrawApplyRespDTO;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 支付客户端，用于对接各支付渠道的 SDK，实现发起支付、退款等功能
 *
 * @author
 */
public interface PayClient {

    /**
     * 获得渠道编号
     *
     * @return 渠道编号
     */
    Long getId();

    /**
     * 调用支付渠道，统一下单
     *
     * @param reqDTO 下单信息
     * @return 各支付渠道的返回结果
     */
    <T> PayCommonResult<PayOrderUnifiedRespDTO<T>> unifiedOrder(PayOrderUnifiedReqDTO reqDTO);

    /**
     * 解析支付单的通知结果
     *
     * @param data 通知结果
     * @return 解析结果
     * @throws Exception 解析失败，抛出异常
     */
    PayOrderNotifyRespDTO parseOrderNotify(PayNotifyDataDTO data) throws Exception;

    /**
     * 调用支付渠道，进行退款
     *
     * @param reqDTO 统一退款请求信息
     * @return 各支付渠道的统一返回结果
     */
    PayCommonResult<PayRefundUnifiedRespDTO> unifiedRefund(PayRefundUnifiedReqDTO reqDTO);

    /**
     * 解析支付退款通知数据
     *
     * @param notifyData 支付退款通知请求数据
     * @return 支付退款通知的Notify DTO
     */
    PayRefundNotifyDTO parseRefundNotify(PayNotifyDataDTO notifyData);

    /**
     * 关闭未支付订单
     *
     * @return
     */
    PayCommonResult<?> unifiedClose(PayCloseUnifiedReqDTO reqDTO);

    /**
     * 查询订单支付结果
     *
     * @param reqDTO
     * @return
     */
    <T> PayCommonResult<PayQueryUnifiedRespDTO<T>> unifiedQuery(PayQueryUnifiedReqDTO reqDTO) throws IOException, NoSuchAlgorithmException, InvalidKeyException, Exception;

    /**
     * 会员绑定支付标识
     *
     * @param reqDTO
     * @return
     */
    PayCommonResult<MemberBindRespDTO> memberBind(MemberBindReqDTO reqDTO);


    /**
     * 创建会员
     *
     * @param reqDTO
     * @return
     */
    PayCommonResult<MemberCreateRespDTO> createMember(MemberCreateReqDTO reqDTO);

    /**
     * 企业H5注册
     *
     * @param reqDTO
     * @return
     */
    PayCommonResult<EnterpriseAccountEstablishRespDTO> establishEnterpriseAccount(EnterpriseAccountEstablishReqDTO reqDTO);

    PayCommonResult<String> queryBankCard(String bizUserId);

    /**
     * 查询余额
     * @param reqDTO
     * @return
     */
    PayCommonResult<QueryBalanceRespDTO> queryBalance(QueryBalanceReqDTO reqDTO);


    PayCommonResult<WithdrawApplyRespDTO> withdrawApply(WithdrawApplyReqDTO reqDTO);
    // TODO @芋艿：后续改成非 default，避免不知道去实现

    /**
     * 验证是否渠道通知
     *
     * @param notifyData 通知数据
     * @return 默认是 true
     */
    default boolean verifyNotifyData(PayNotifyDataDTO notifyData) {
        return true;
    }

    // TODO @芋艿：后续改成非 default，避免不知道去实现

    /**
     * 判断是否为退款通知
     *
     * @param notifyData 通知数据
     * @return 默认是 false
     */
    default boolean isRefundNotify(PayNotifyDataDTO notifyData) {
        return false;
    }

}
